<script setup lang='ts'>
// code resource: https://codepen.io/BrianCross/pen/PoWapLP

/**
 * Notice there's no actual scrolling in the demo below
 * but you can use your mouse wheel (or swipe on touch devices) to initiate movement so it "feels" like a scroll
 */

import gsap from 'gsap'

const theme = {
  'bg-gradient': 'linear-gradient(180deg, rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0.3) 100%)'
}

const sections = ref<HTMLElement[]>([])
const images = ref<HTMLElement[]>([])
const headings = ref<HTMLElement[]>([])
const outerWrappers = ref<HTMLElement[]>([])
const innerWrappers = ref<HTMLElement[]>([])
const headingTexts = ref([
  'Scroll down',
  'Tiga Altman',
  '@刘仁钦',
  'Powered by GSAP',
  'Keep scrolling'
])

let listening = false
let direction = 'down'
let current: number
let next = 0

const touch = {
  startX: 0,
  startY: 0,
  dx: 0,
  dy: 0,
  startTime: 0,
  dt: 0
}

const tlDefaults = {
  ease: 'slow.inOut',
  duration: 1.25
}

function splitHeading(heading: string) {
  return heading.split('')
}

function revealSectionHeading() {
  return gsap.to(`section:nth-of-type(${next + 1}) .char`, {
    autoAlpha: 1,
    yPercent: 0,
    duration: 1,
    ease: 'power2',
    stagger: {
      // each: 0.02,
      each: 0.1, // 增加动画开始时间间隔
      from: 'random',
    }
  })
}

function slideIn() {
  if (current !== undefined)
    gsap.set(sections.value[current], { zIndex: 0 })

  gsap.set(sections.value[next], { autoAlpha: 1, zIndex: 1 })
  gsap.set(images.value[next], { yPercent: 0 })
  gsap.set(`section:nth-of-type(${next + 1}) .char`, { autoAlpha: 0, yPercent: 100 })

  const tl = gsap.timeline({
    paused: true,
    defaults: tlDefaults,
    onComplete: () => {
      listening = true
      current = next
    },
  })
    .to([outerWrappers.value[next], innerWrappers.value[next]], { yPercent: 0 }, 0)
    .from(images.value[next], { yPercent: 15 }, 0)
    .add(revealSectionHeading(), 0)

  if (current !== undefined) {
    tl.add(
      gsap.to(images.value[current], {
        yPercent: -15,
        ...tlDefaults,
      }),
      0,
    ).add(
      gsap.timeline()
        .set(outerWrappers.value[current], { yPercent: 100 })
        .set(innerWrappers.value[current], { yPercent: -100 })
        .set(images.value[current], { yPercent: 0 })
        .set(sections.value[current], { autoAlpha: 0 }),
    )
  }

  tl.play(0)
}

function slideOut() {
  gsap.set(sections.value[current], { zIndex: 1 })
  gsap.set(sections.value[next], { autoAlpha: 1, zIndex: 0 })
  gsap.set(`section:nth-of-type(${next + 1}) .char`, { autoAlpha: 0, yPercent: 100 })
  gsap.set([outerWrappers.value[next], innerWrappers.value[next]], { yPercent: 0 })
  gsap.set(images.value[next], { yPercent: 0 })

  gsap.timeline({
    defaults: tlDefaults,
    onComplete: () => {
      listening = true
      current = next
    },
  })
    .to(outerWrappers.value[current], { yPercent: 100 }, 0)
    .to(innerWrappers.value[current], { yPercent: -100 }, 0)
    .to(images.value[current], { yPercent: 15 }, 0)
    .from(images.value[next], { yPercent: -15 }, 0)
    .add(revealSectionHeading(), '>-1')
    .set(images.value[current], { yPercent: 0 })
}

function handleDirection() {
  listening = false

  if (direction === 'down') {
    next = current + 1
    if (next >= sections.value.length)
      next = 0
    slideIn()
  }

  if (direction === 'up') {
    next = current - 1
    if (next < 0)
      next = sections.value.length - 1
    slideOut()
  }
}

function handleWheel(e: WheelEvent) {
  if (!listening)
    return
  direction = e.deltaY > 0 ? 'down' : 'up'
  handleDirection()
}

function handleTouchStart(e: TouchEvent) {
  if (!listening)
    return
  const t = e.changedTouches[0]
  touch.startX = t.pageX
  touch.startY = t.pageY
}

function handleTouchMove(e: TouchEvent) {
  if (!listening)
    return
  e.preventDefault()
}

function handleTouchEnd(e: TouchEvent) {
  if (!listening)
    return
  const t = e.changedTouches[0]
  touch.dx = t.pageX - touch.startX
  touch.dy = t.pageY - touch.startY
  if (touch.dy > 10)
    direction = 'up'
  if (touch.dy < -10)
    direction = 'down'
  handleDirection()
}

onMounted(() => {
  sections.value = gsap.utils.toArray('section')
  images.value = gsap.utils.toArray('.bg')
  headings.value = gsap.utils.toArray('.section-heading')
  outerWrappers.value = gsap.utils.toArray('.outer')
  innerWrappers.value = gsap.utils.toArray('.inner')

  gsap.set(outerWrappers.value, { yPercent: 100 })
  gsap.set(innerWrappers.value, { yPercent: -100 })

  window.addEventListener('wheel', handleWheel)
  window.addEventListener('touchstart', handleTouchStart)
  window.addEventListener('touchmove', handleTouchMove)
  window.addEventListener('touchend', handleTouchEnd)

  slideIn()
})
</script>

<template>
  <div class="content">
    <header class="fixed z-3 h-60 w-full flex items-center justify-around tracking-0.5em">
      <div>LiuPeng</div>
      <div><a href="https://beierzhijin.github.io/developer-guide/">Original By K</a></div>
    </header>
    <section class="first">
      <div class="outer">
        <div class="inner">
          <div class="bg">
            <h2 class="section-heading">
              <span v-for="(char, index) in splitHeading(headingTexts[0])" :key="index" class="char">{{ char }}</span>
            </h2>
          </div>
        </div>
      </div>
    </section>
    <section class="second">
      <div class="outer">
        <div class="inner">
          <div class="bg">
            <h2 class="section-heading">
              <span v-for="(char, index) in splitHeading(headingTexts[1])" :key="index" class="char">{{ char }}</span>
            </h2>
          </div>
        </div>
      </div>
    </section>
    <section class="third">
      <div class="outer">
        <div class="inner">
          <div class="bg">
            <h2 class="section-heading">
              <span v-for="(char, index) in splitHeading(headingTexts[2])" :key="index" class="char char_me">{{ char
              }}</span>
            </h2>
          </div>
        </div>
      </div>
    </section>
    <section class="fourth">
      <div class="outer">
        <div class="inner">
          <div class="bg">
            <h2 class="section-heading">
              <span v-for="(char, index) in splitHeading(headingTexts[3])" :key="index" class="char">{{ char }}</span>
            </h2>
          </div>
        </div>
      </div>
    </section>
    <section class="fifth">
      <div class="outer">
        <div class="inner">
          <div class="bg">
            <h2 class="section-heading">
              <span v-for="(char, index) in splitHeading(headingTexts[4])" :key="index" class="char">{{ char }}</span>
            </h2>
          </div>
        </div>
      </div>
    </section>
  </div>
</template>

<style lang="scss" scoped>
@use '@/assets/fonts/Italiana.css';
@use '@/assets/fonts/Cormorant_Garamond.css';
@use '@/assets/fonts/Zhi_Mang_Xing.css';
// @use '@/assets/fonts/Liu_Jian_Mao_Cao.css';

.content {
  height: 100vh;
  font-family: "Cormorant Garamond", serif;
  color: white;
  background: black;
  text-transform: uppercase; // 将文本中的所有字母转换为大写字母
}

header {
  font-family: "Italiana", sans-serif;
  font-size: clamp(9px, 2vw, 60px);
}

a {
  color: #fff;
  text-decoration: none;
}

h2 {
  font-size: clamp(1rem, 5vw, 5rem);
  font-weight: 400;
  text-align: center;
  letter-spacing: 0.5em;
  margin-right: -0.5em;
  color: hsl(0, 0%, 80%);
  width: 90vw;
  max-width: 1200px;
}

section {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  visibility: hidden;

  .outer,
  .inner {
    width: 100%;
    height: 100%;
    overflow-y: hidden;
  }

  .bg {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    height: 100%;
    width: 100%;
    top: 0;
    background-size: cover;
    background-position: center;

    h2 {
      z-index: 2;
    }
  }
}

.first {
  .bg {
    background-image: v-bind('theme["bg-gradient"]'),
      url(https://images.unsplash.com/photo-1617478755490-e21232a5eeaf?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYxNzU1NjM5NA&ixlib=rb-1.2.1&q=75&w=1920);
  }
}

.second {
  .bg {
    background-image: v-bind('theme["bg-gradient"]'),
      url("https://images.unsplash.com/photo-1617128734662-66da6c1d3505?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYxNzc3NTM3MA&ixlib=rb-1.2.1&q=75&w=1920");
  }
}

.third {
  .bg {
    background-image: v-bind('theme["bg-gradient"]'),
      url(https://images.unsplash.com/photo-1617438817509-70e91ad264a5?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYxNzU2MDk4Mg&ixlib=rb-1.2.1&q=75&w=1920);
  }
}

.fourth {
  .bg {
    background-image: v-bind('theme["bg-gradient"]'),
      url(https://images.unsplash.com/photo-1617412327653-c29093585207?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYxNzU2MDgzMQ&ixlib=rb-1.2.1&q=75&w=1920);
  }
}

.fifth {
  .bg {
    background-image: v-bind('theme["bg-gradient"]'),
      url("https://images.unsplash.com/photo-1617141636403-f511e2d5dc17?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYxODAzMjc4Mw&ixlib=rb-1.2.1&q=75w=1920");
    background-position: 50% 45%;
  }
}

h2 * {
  will-change: transform;
}

// 增加
.char {
  text-shadow: 2px 2px 4px rgba(190, 30, 30, 0.5); // 添加文字阴影
  background: linear-gradient(to right, #fff, #ccc); // 添加颜色渐变
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.char_me {
  // font-family: "Liu Jian Mao Cao", sans-serif;
  font-family: "Zhi Mang Xing", sans-serif;
  font-size: 7vw;
  text-transform: uppercase;
  color: #fff;
  background: linear-gradient(to right, rgb(255, 230, 0), rgb(255, 174, 0));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
</style>
